package cn.yj.register.configType;

import cn.yj.register.Provider;
import cn.yj.register.RegisterException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

/**
 * @author Liyj
 */
public class LocalConfigRegister implements IConfigRegister, InitializingBean {

	private static final Logger log = LoggerFactory.getLogger(LocalConfigRegister.class);

	private static final Object lock = new Object();

	private static final String HOST_FILE = ".host-list";


	@Override
	public boolean register(Provider provider) {
		try {
			Map<String, Provider> providerMap = getProvider();
			if (providerMap == null) {
				providerMap = new HashMap<>();
			}
			providerMap.put(provider.getAddress(), provider);
			writeToFile(JSON.toJSONString(providerMap));
			log.info("服务注册：" + provider.getAddress());
		} catch (Exception e) {
			log.error("服务注册异常", e);
			return false;
		}
		return true;
	}

	@Override
	public void updateProvider(Provider provider) {
		Map<String, Provider> providerMap = getProvider();
		String address = provider.getAddress();
		providerMap.put(address, provider);
		writeToFile(JSON.toJSONString(providerMap));
	}

	private void writeToFile(String text) {
		synchronized (lock) {
			try {
				File file = new File(getHostFile());
				Writer out = new FileWriter(file);
				out.write(text);
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public Map<String, Provider> getProvider() {
		synchronized (lock) {
			File file = new File(getHostFile());
			FileInputStream fin = null;
			StringBuffer buffer = new StringBuffer();
			try {
				fin = new FileInputStream(file);
				FileChannel channel = fin.getChannel();
				int capacity = 5000;
				ByteBuffer bf = ByteBuffer.allocate(capacity);
				int length;
				while ((length = channel.read(bf)) != -1) {
					bf.clear();
					byte[] bytes = bf.array();
					buffer.append(new String(bytes, 0, length, "UTF-8"));
				}
				channel.close();
			} catch (FileNotFoundException var18) {
				var18.printStackTrace();
			} catch (IOException var19) {
				var19.printStackTrace();
			} finally {
				if (fin != null) {
					try {
						fin.close();
					} catch (IOException var17) {
						var17.printStackTrace();
					}
				}
			}
			if (buffer.toString().equals("")) {
				return null;
			}
			Map<String, Provider> stringProviderHashMap = new HashMap<>();
			Map<String, JSONObject> stringProviderMap = JSONObject.parseObject(buffer.toString(), Map.class);
			stringProviderMap.entrySet().forEach(map -> {
				JSONObject value = map.getValue();
				JSONArray array = (JSONArray) value.get("beanNames");
				List<String> beanNames = array.toJavaList(String.class);

				JSONArray array1 = (JSONArray) value.get("classBeanNames");
				List<String> classBeanNames = array1.toJavaList(String.class);

				Provider provider = JSON.parseObject(JSON.toJSONString(value), Provider.class);
				provider.setBeanNames(new HashSet<>(beanNames));
				provider.setClassBeanNames(new HashSet<>(classBeanNames));
				stringProviderHashMap.put(map.getKey(), provider);
			});
			return stringProviderHashMap;
		}
	}

	@Override
	public Provider getProvider(String host) {
		return getProvider().get(host);
	}

	@Override
	public void logout(String host) {
		Map<String, Provider> provider = getProvider();
		provider.remove(host);
		writeToFile(JSON.toJSONString(provider));
	}

	@Override
	public String configType() {
		return "LOCAL";
	}


	private void initHostFile(String host) throws IOException {
		String hostFile = getHostFile();
	}

	private String getHostFile() {
		String homePath = System.getProperty("user.home");
		String path = homePath.concat("/").concat(HOST_FILE);
		File file = new File(path);
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				throw new RegisterException(e);
			}
		}
		return path;
	}


	@Override
	public void afterPropertiesSet() throws Exception {
		
	}
}
